#if defined(_MSC_VER)
#pragma once
#endif

#ifndef LM_TEXTURE_IMAGE_H
#define LM_TEXTURE_IMAGE_H

#include "../core/lm.h"
#include "../core/memory.h"
#include "../core/mipmap.h"
#include "../core//textureMap.h"
#include "../core/imageio.h"
#include "../core/intersection.h"

#include <map>

struct TexInfo {
	TexInfo(const string &f, bool dt, float ma, ImageWrap wm)
		: filename(f), doTrilinear(dt), maxAniso(ma), wrapMode(wm) { }
	string filename;
	bool doTrilinear;
	float maxAniso;
	ImageWrap wrapMode;
	bool operator<(const TexInfo &t2) const {
		if (filename != t2.filename) return filename < t2.filename;
		if (doTrilinear != t2.doTrilinear) return doTrilinear < t2.doTrilinear;
		if (maxAniso != t2.maxAniso) return maxAniso < t2.maxAniso;
		return wrapMode < t2.wrapMode;
	}
};

template<class T> class ImageTexture : public Texture<T> {
public:
	ImageTexture(Reference<TextureMap> m, const string &filename, bool doTrilinear, float maxAniso, ImageWrap wrapMode);
	MIPMap<T> *GetTexture(const string &filename, bool doTrilinear, float maxAniso, ImageWrap wrap);
	static void ClearCache() {
		typename std::map<TexInfo, MIPMap<T> *>::iterator iter;
		iter = textures.begin();
		while (iter != textures.end()) {
			delete iter->second;
			++iter;
		}
		textures.erase(textures.begin(), textures.end());
	}
	T Evaluate(const Intersection &isect) const;
	~ImageTexture();
private:
	static void convert(const Spectrum &from, Spectrum *to) {
		*to = from;
	}
	static void convert(const Spectrum &from, float *to) {
		*to = from.y();
	}
	static std::map<TexInfo, MIPMap<T> *> textures;
	MIPMap<T> *mipmap;
	Reference<TextureMap> mapping;
};

#endif	// LM_TEXTURE_IMAGE_H